package cn.theten52.demo.patterns.design.behavior.interpreter;

import java.util.Map;
import java.util.Stack;

/**
 * 计算器
 *
 * @author wangjin
 * @date 2021/1/6
 */
public class Calculator {
    private Expression expression;

    public Calculator(String exp) {
        Expression left;
        Expression right;
        Stack<Expression> stack = new Stack<>();
        char[] chars = exp.toCharArray();
        for (int i = 0, len = chars.length; i < len; i++) {
            switch (chars[i]) {
                case '+':
                    // 从栈中取回上一个压入的元素作为左侧表达式
                    left = stack.pop();
                    // 指针后移一位得到右侧表达式
                    right = new VarExp(String.valueOf(chars[++i]));
                    // 将计算结果压回栈中
                    stack.push(new Add(left, right));
                    break;
                case '-':
                    left = stack.pop();
                    right = new VarExp(String.valueOf(chars[++i]));
                    stack.push(new Minus(left, right));
                    break;
                default:
                    // 如果是非运算符，则生成一个非终结表达式，然后压和栈中
                    stack.push(new VarExp(String.valueOf(chars[i])));
                    break;
            }
        }
        // 遍历完成后取回栈中的元素
        this.expression = stack.pop();
    }

    /**
     * 实际上，计算已经在构造器里完成了，这里只是取回结果的值
     *
     * @param var
     * @return
     */
    public double cal(Map<String, Double> var) {
        return this.expression.interpreter(var);
    }
}
